package com.oim.fx.view;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.lang3.StringUtils;

import com.oim.core.bean.Department;
import com.oim.core.bean.DepartmentMember;
import com.oim.core.business.box.DepartmentBox;
import com.oim.core.business.box.PersonalBox;
import com.oim.core.business.manage.DepartmentChatManage;
import com.oim.core.business.manager.ChatManage;
import com.oim.core.business.manager.HeadImageManager;
import com.oim.core.business.manager.IconButtonManage;
import com.oim.core.business.manager.PersonalManager;
import com.oim.core.business.module.SystemModule;
import com.oim.core.business.view.FindView;
import com.oim.core.business.view.MainView;
import com.oim.core.business.view.NoticeView;
import com.oim.core.business.view.ThemeView;
import com.oim.core.business.view.UpdatePasswordView;
import com.oim.core.business.view.UserDataEditView;
import com.oim.core.common.util.AppCommonUtil;
import com.oim.fx.common.box.ImageBox;
import com.oim.fx.common.component.IconPane;
import com.oim.fx.ui.MainFrame;
import com.oim.fx.ui.SimpleMainFrame;
import com.oim.fx.ui.chat.SimpleHead;
import com.oim.fx.ui.list.HeadItem;
import com.oim.fx.ui.list.ListNodePanel;
import com.oim.fx.ui.main.EnterpriseMainPopupMenu;
import com.oim.fx.ui.main.MainPopupMenu;
import com.oim.ui.fx.classics.list.TreeNodePane;
import com.only.fx.common.action.ExecuteAction;
import com.onlyxiahui.app.base.AppContext;
import com.onlyxiahui.im.bean.UserData;

import javafx.application.Platform;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Side;
import javafx.scene.Cursor;
import javafx.scene.Node;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.image.Image;
import javafx.scene.input.ContextMenuEvent;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Border;
import javafx.scene.layout.StackPane;

/**
 * @author: XiaHui
 * @date: 2016年10月11日 上午9:17:32
 */
public class SimpleMainViewImpl extends MainViewImpl implements MainView, EnterpriseMainView {

	protected MainPopupMenu mainPopupMenu;

	private Map<String, Map<String, SimpleHead>> userHeadMap = new ConcurrentHashMap<String, Map<String, SimpleHead>>();
	private Map<String, Map<String, TreeItem<Object>>> userTreeItemMap = new ConcurrentHashMap<String, Map<String, TreeItem<Object>>>();

	private Map<String, TreeNodePane> departmentHeadLabelMap = new ConcurrentHashMap<String, TreeNodePane>();
	private Map<String, TreeItem<Object>> departmentTreeItemMap = new ConcurrentHashMap<String, TreeItem<Object>>();

	private Map<String, HeadItem> departmentHeadMap = new ConcurrentHashMap<String, HeadItem>();
	TreeNodePane rootPane;
	TreeItem<Object> root;
	TreeView<Object> treeView;

	ListNodePanel departmentListPane;

	public SimpleMainViewImpl(AppContext appContext) {
		super(appContext);
	}

	protected void initialize() {
		super.initialize();
		rootPane = new TreeNodePane();
		root = new TreeItem<Object>(rootPane);
		treeView = new TreeView<Object>();

		departmentListPane = new ListNodePanel();
		departmentListPane.setText("部门讨论组");
		departmentListPane.setNumberText("[0]");
		groupRoot.addNode(departmentListPane);

		mainPopupMenu = new EnterpriseMainPopupMenu();
	}

	protected void initIocn() {

		Image businessImage = ImageBox.getImageClassPath("/resources/main/images/top/skin.png");

		IconPane iconButton = new IconPane(businessImage);
		mainFrame.addBusinessIcon(iconButton);
		iconButton.setOnMouseClicked(new EventHandler<MouseEvent>() {

			@Override
			public void handle(MouseEvent event) {
				ThemeView findView = appContext.getSingleView(ThemeView.class);
				findView.setVisible(true);
			}
		});

		///////////////////////////////////////////// function
		Image normalImage = ImageBox.getImageClassPath("/resources/main/images/bottom/menu_btn_normal.png");
		Image hoverImage = ImageBox.getImageClassPath("/resources/main/images/bottom/menu_btn2_down.png");
		Image pressedImage = ImageBox.getImageClassPath("/resources/main/images/bottom/menu_btn_highlight.png");

		iconButton = new IconPane(normalImage, hoverImage, pressedImage);
		mainFrame.addFunctionIcon(iconButton);
		iconButton.setOnMouseClicked(new EventHandler<MouseEvent>() {

			@Override
			public void handle(MouseEvent event) {
				Object source = event.getSource();
				if (source instanceof Node) {
					Node node = (Node) source;
					mainPopupMenu.show(node, Side.TOP, node.getLayoutX(), node.getLayoutY());
				}
			}
		});

		normalImage = ImageBox.getImageClassPath("/resources/main/images/bottom/message.png");
		hoverImage = ImageBox.getImageClassPath("/resources/main/images/bottom/message_highlight.png");
		pressedImage = ImageBox.getImageClassPath("/resources/main/images/bottom/message_down.png");

		iconButton = new IconPane(normalImage, hoverImage, pressedImage);
		mainFrame.addFunctionIcon(iconButton);

		iconButton.setOnMouseClicked(new EventHandler<MouseEvent>() {

			@Override
			public void handle(MouseEvent event) {
				NoticeView view = appContext.getSingleView(NoticeView.class);
				view.setVisible(true);
			}
		});

		IconButtonManage ibm = appContext.getManager(IconButtonManage.class);
		ibm.put("notice_icon_button", iconButton);

		normalImage = ImageBox.getImageClassPath("/resources/main/images/bottom/find.png");
		hoverImage = ImageBox.getImageClassPath("/resources/main/images/bottom/find_hover.png");
		pressedImage = ImageBox.getImageClassPath("/resources/main/images/bottom/find_down.png");

		iconButton = new IconPane("查找", normalImage, hoverImage, pressedImage);
		mainFrame.addFunctionIcon(iconButton);
		iconButton.setOnMouseClicked(new EventHandler<MouseEvent>() {

			@Override
			public void handle(MouseEvent event) {
				FindView findView = appContext.getSingleView(FindView.class);
				findView.setVisible(true);
			}
		});

	}

	protected void initComponent() {
		
		Image normalImage = ImageBox.getImagePath("Resources/Images/Enterprise/Main/Tab/icon_framework_normal_1.png");
		Image hoverImage = ImageBox.getImagePath("Resources/Images/Enterprise/Main/Tab/icon_framework_hover_1.png");
		Image selectedImage = ImageBox.getImagePath("Resources/Images/Enterprise/Main/Tab/icon_framework_selected_1.png");

		treeView.setShowRoot(false);
		treeView.setRoot(root);
		treeView.setBorder(Border.EMPTY);
		// treeView.setBackground(Background.EMPTY);
		// treeView.setBlendMode(BlendMode.DARKEN);// 透明
		treeView.setOnMouseEntered(e -> {
			treeView.setCursor(Cursor.DEFAULT);
		});

		StackPane userList = new StackPane();
		userList.getChildren().add(treeView);
		mainFrame.addTab(normalImage, hoverImage, selectedImage, userList);

		normalImage = ImageBox.getImageClassPath("/resources/main/images/panel/icon_contacts_normal.png");
		hoverImage = ImageBox.getImageClassPath("/resources/main/images/panel/icon_contacts_hover.png");
		selectedImage = ImageBox.getImageClassPath("/resources/main/images/panel/icon_contacts_selected.png");

		mainFrame.addTab(normalImage, hoverImage, selectedImage, userRoot);

		normalImage = ImageBox.getImageClassPath("/resources/main/images/panel/icon_group_normal.png");
		hoverImage = ImageBox.getImageClassPath("/resources/main/images/panel/icon_group_hover.png");
		selectedImage = ImageBox.getImageClassPath("/resources/main/images/panel/icon_group_selected.png");

		mainFrame.addTab(normalImage, hoverImage, selectedImage, groupRoot);

		normalImage = ImageBox.getImageClassPath("/resources/main/images/panel/icon_last_normal.png");
		hoverImage = ImageBox.getImageClassPath("/resources/main/images/panel/icon_last_hover.png");
		selectedImage = ImageBox.getImageClassPath("/resources/main/images/panel/icon_last_selected.png");

		mainFrame.addTab(normalImage, hoverImage, selectedImage, lastRoot);

		normalImage = ImageBox.getImagePath("Resources/Images/Main/Tab/pc_status_normal.png");
		hoverImage = ImageBox.getImagePath("Resources/Images/Main/Tab/pc_status_hover.png");
		selectedImage = ImageBox.getImagePath("Resources/Images/Main/Tab/pc_status_selected.png");
	}

	protected void initEvent() {
		super.initEvent();
//		groupRoot.setOnContextMenuRequested(new EventHandler<ContextMenuEvent>() {
//
//			@Override
//			public void handle(ContextMenuEvent event) {
//				groupPopupMenu.show(mainFrame, event.getScreenX(), event.getScreenY());
//				event.consume();
//			}
//		});
//		statusPopupMenu.setStatusAction(new ExecuteAction() {
//
//			@Override
//			public <T, E> E execute(T value) {
//				if (value instanceof String) {
//					PersonalManage pm = appContext.getManage(PersonalManage.class);
//					pm.updateStatus((String) value);
//				}
//				return null;
//			}
//
//		});
		mainPopupMenu.setStatusAction(new ExecuteAction() {

			@Override
			public <T, E> E execute(T value) {
				if (value instanceof String) {
					PersonalManager pm = appContext.getManager(PersonalManager.class);
					pm.updateStatus((String) value);
				}
				return null;
			}

		});
//		mainFrame.setStatusOnMouseClicked(new EventHandler<MouseEvent>() {
//
//			@Override
//			public void handle(MouseEvent event) {
//				Object source = event.getSource();
//				if (source instanceof Node) {
//					Node node = (Node) source;
//					statusPopupMenu.show(node, Side.BOTTOM, node.getLayoutX(), node.getLayoutY());
//				}
//			}
//		});
//
//		mainFrame.setHeadOnMouseClicked(m -> {
//			PersonalBox pb=appContext.getBox(PersonalBox.class);
//			UserData user = pb.getUserData();
//			UserDataView v = appContext.getSingleView(UserDataView.class);
//			v.setVisible(true);
//			v.showUserData(user);
//		});
//
		mainPopupMenu.setQuitAction(new EventHandler<ActionEvent>() {

			@Override
			public void handle(ActionEvent event) {
				SystemModule sm = appContext.getModule(SystemModule.class);
				sm.exit();
			}
		});
		mainPopupMenu.setUpdatePasswordAction(new EventHandler<ActionEvent>() {

			@Override
			public void handle(ActionEvent event) {
				UpdatePasswordView upv = appContext.getSingleView(UpdatePasswordView.class);
				upv.setVisible(true);
			}
		});
//
		mainPopupMenu.setUpdateAction(new EventHandler<ActionEvent>() {

			@Override
			public void handle(ActionEvent event) {
				UserDataEditView view = appContext.getSingleView(UserDataEditView.class);
				view.setVisible(true);
			}
		});
//
//		groupPopupMenu.setAddAction(new EventHandler<ActionEvent>() {
//
//			@Override
//			public void handle(ActionEvent event) {
//				GroupEditView view = appContext.getSingleView(GroupEditView.class);
//				view.setGroup(null);
//				view.setVisible(true);
//			}
//		});
//
//		groupPopupMenu.setFindAction(new EventHandler<ActionEvent>() {
//
//			@Override
//			public void handle(ActionEvent event) {
//				FindView findView = appContext.getSingleView(FindView.class);
//				findView.selectedTab(1);
//				findView.setVisible(true);
//			}
//		});
//
//		gcm.setUpdateAction(g -> {
//			GroupEditView view = appContext.getSingleView(GroupEditView.class);
//			view.setGroup(g);
//			view.setVisible(true);
//		});
//
//		gcm.setShowAction(g -> {
//			GroupDataView v = appContext.getSingleView(GroupDataView.class);
//			v.setGroup(g);
//			v.setVisible(true);
//		});

//		ucm.setShowAction(u -> {
//			UserDataView v = appContext.getSingleView(UserDataView.class);
//			v.showUserData(u);
//			v.setVisible(true);
//		});
	}

	public MainFrame createFrame() {
		return new SimpleMainFrame();
	}

	@Override
	public void clearGroupCategory() {
		Platform.runLater(new Runnable() {
			@Override
			public void run() {
				groupRoot.clearNode();
				groupRoot.addNode(departmentListPane);
			}
		});
	}
	
	public void addOrUpdateUser(String userCategoryId, UserData userData) {
		super.addOrUpdateUser(userCategoryId, userData);
	}

	@Override
	public void addOrUpdateDepartmentUserData(String departmentId, UserData userData) {
		Platform.runLater(new Runnable() {
			@Override
			public void run() {

				String userId = userData.getId();
				Map<String, SimpleHead> headMap = userHeadMap.get(departmentId);
				if (null == headMap) {
					headMap = new HashMap<String, SimpleHead>();
					userHeadMap.put(departmentId, headMap);
				}
				SimpleHead head = headMap.get(userId);
				if (null == head) {
					head = new SimpleHead();
					head.getStyleClass().remove("list-head-item");
					head.setHeadSize(20);
					head.setHeadRadius(20);
					headMap.put(userId, head);
				}

				setUserDataHeadEvent(head, userData);
				setUserDataHead(head, userData);

				Map<String, TreeItem<Object>> headTreeItemMap = userTreeItemMap.get(departmentId);
				if (null == headTreeItemMap) {
					headTreeItemMap = new HashMap<String, TreeItem<Object>>();
					userTreeItemMap.put(departmentId, headTreeItemMap);
				}

				TreeItem<Object> headTreeItem = headTreeItemMap.get(userId);
				if (null == headTreeItem) {
					headTreeItem = new TreeItem<Object>(head);
					headTreeItemMap.put(userId, headTreeItem);
				}

				TreeItem<Object> node = departmentTreeItemMap.get(departmentId);
				if (null != node) {
					ObservableList<TreeItem<Object>> list = node.getChildren();
					int size = list.size();

					if (!list.contains(headTreeItem)) {
						if (size > 0) {
							list.add(size, headTreeItem);
						} else {
							list.add(headTreeItem);
						}
					}
				}
			}
		});
	}

	@Override
	public void updateDepartmentMemberCount(String departmentId, int totalCount, int onlineCount) {
		Platform.runLater(new Runnable() {
			@Override
			public void run() {
				TreeNodePane node = departmentHeadLabelMap.get(departmentId);
				if (null != node) {
					node.setNumberText("[" + onlineCount + "/" + totalCount + "]");
				}
			}
		});
	}

	@Override
	public void showUserHeadPulse(String userId, boolean pulse) {
		super.showUserHeadPulse(userId, pulse);
		Platform.runLater(new Runnable() {
			@Override
			public void run() {
				DepartmentBox db = appContext.getBox(DepartmentBox.class);
				List<DepartmentMember> list = db.getUserInDepartmentMemberList(userId);
				for (DepartmentMember dm : list) {

					Map<String, SimpleHead> headMap = userHeadMap.get(dm.getDepartmentId());
					if (null != headMap) {
						SimpleHead head = headMap.get(userId);
						if (null != head) {
							head.setPulse(pulse);
						}
					}
				}
			}
		});
	}

	@Override
	public void addOrUpdateLastDepartment(Department department, String text) {
		Platform.runLater(new Runnable() {
			@Override
			public void run() {
				HeadItem head = getDepartmentLastHeadItem(department);
				setDepartmentLastHead(head, department, text);
				addLastItem(head);
			}
		});
	}

	protected void setDepartmentLastHead(HeadItem head, Department group, String text) {
		String headPath = "Resources/Images/Enterprise/Head/2.png";
		Image image = ImageBox.getImagePath(headPath);
		head.setHeadImage(image);
		head.setRemark(group.getName());
		if (null != text && !"".equals(text)) {
			head.setShowText(text);
		}
	}

	protected void setDepartmentHeadEvent(HeadItem head, Department department) {
		head.setOnMouseClicked((MouseEvent me) -> {
			if (me.getClickCount() == 2) {
				DepartmentChatManage chatManage = appContext.getManager(DepartmentChatManage.class);
				chatManage.showCahtFrame(department);
			} else if (me.getButton() == MouseButton.SECONDARY) {
			}
			me.consume();
		});
	}

	protected HeadItem getDepartmentLastHeadItem(Department department) {
		HeadItem head = lastMap.get(department.getId());
		if (null == head) {
			head = new HeadItem();
			lastMap.put(department.getId(), head);
			setDepartmentHeadEvent(head, department);
		}
		return head;
	}

	protected void setUserDataHead(SimpleHead head, UserData userData) {
		HeadImageManager him = appContext.getManager(HeadImageManager.class);
		Image image = him.getUserHeadImage(userData.getId(), userData.getHead(), 40);

		String text = AppCommonUtil.getDefaultShowName(userData);
		head.setImage(image);
		head.setText(text);// 昵称

		// 如果用户不是在线状态，则使其头像变灰
		if (AppCommonUtil.isOffline(userData.getStatus())) {
			head.setGray(true);
		} else {
			head.setGray(false);
		}
	}

	protected void setUserDataHeadEvent(SimpleHead head, UserData userData) {
		head.setOnContextMenuRequested(new EventHandler<ContextMenuEvent>() {

			@Override
			public void handle(ContextMenuEvent e) {
				uhmv.setUserData(userData);
				uhmv.show(mainFrame, e.getScreenX(), e.getScreenY());
				e.consume();
			}
		});
		head.setOnMouseClicked((MouseEvent me) -> {
			if (me.getClickCount() == 2) {
				ChatManage chatManage = appContext.getManager(ChatManage.class);
				chatManage.showCahtFrame(userData);
			}
			me.consume();
		});
	}

	@Override
	public void showDepartmentHeadPulse(String departmentId, boolean pulse) {
		HeadItem head = departmentHeadMap.get(departmentId);
		if (null != head) {
			head.setPulse(pulse);
		}
	}

	

	@Override
	public void addOrUpdateDepartment(Department department) {
		Platform.runLater(new Runnable() {
			@Override
			public void run() {
				String departmentId = department.getId();
				TreeNodePane node = getDepartmentPane(departmentId);
				setDepartmentInfo(department, node);
				joinSuperior(department);
				addOrUpdate(department);
				setUserHeadList(departmentId);
			}
		});
	}

	private void addOrUpdate(Department department) {
		PersonalBox pb=appContext.getBox(PersonalBox.class);
		UserData user = pb.getUserData();
		String userId = user.getId();
		String departmentId = department.getId();

		DepartmentBox db = appContext.getBox(DepartmentBox.class);
		if (db.inDepartmentIncludeSuperior(userId, departmentId)) {
			HeadItem head = departmentHeadMap.get(departmentId);
			if (null == head) {
				head = new HeadItem();
				departmentHeadMap.put(departmentId, head);
			}
			String headPath = "Resources/Images/Enterprise/Head/2.png";
			Image image = ImageBox.getImagePath(headPath);
			head.setHeadImage(image);
			head.setRemark(department.getName());

			setDepartmentHeadEvent(head, department);

			departmentListPane.addItem(head);
			int size = departmentListPane.itemSize();
			departmentListPane.setNumberText("[" + size + "]");
		}
	}

	private void joinSuperior(List<Department> departmentList) {
		for (Department department : departmentList) {
			joinSuperior(department);
		}
	}

	private void joinSuperior(Department department) {
		String id = department.getId();
		String superiorId = department.getSuperiorId();
		TreeItem<Object> item = departmentTreeItemMap.get(id);
		TreeItem<Object> superiorItem = departmentTreeItemMap.get(superiorId);

		if (null != item) {
			if ("0".equals(superiorId) || StringUtils.isBlank(superiorId)) {
				root.getChildren().add(item);
			} else {
				if (null != superiorItem) {
					ObservableList<TreeItem<Object>> list = superiorItem.getChildren();
					if (!list.contains(item)) {
						list.add(0, item);
					}
				}
			}
		}
	}

	private TreeNodePane getDepartmentPane(String departmentId) {
		TreeNodePane node = departmentHeadLabelMap.get(departmentId);
		if (null == node) {
			node = new TreeNodePane();
			node.getStyleClass().remove("list-top-title");
			departmentHeadLabelMap.put(departmentId, node);
		}

		TreeItem<Object> item = departmentTreeItemMap.get(departmentId);
		if (null == item) {
			item = new TreeItem<Object>(node);
			departmentTreeItemMap.put(departmentId, item);
		}
		return node;
	}

	private void setDepartmentInfo(Department department, TreeNodePane node) {
		node.setText(department.getName());
		node.setNumberText("[0]");
	}

	private void setUserHeadList(String departmentId) {
		TreeItem<Object> departmentItem = departmentTreeItemMap.get(departmentId);
		if (null != departmentItem) {
			DepartmentBox db = appContext.getBox(DepartmentBox.class);
			List<DepartmentMember> userIdList = db.getDepartmentMemberList(departmentId);
			if (null != userIdList) {
				for (DepartmentMember dm : userIdList) {
					String userId = dm.getUserId();
					Map<String, TreeItem<Object>> userHeadTreeItemMap = userTreeItemMap.get(departmentId);
					if (null != userHeadTreeItemMap) {
						TreeItem<Object> userHeadTreeItem = userHeadTreeItemMap.get(userId);
						if (null != userHeadTreeItem) {
							ObservableList<TreeItem<Object>> list = departmentItem.getChildren();
							int size = list.size();

							if (!list.contains(userHeadTreeItem)) {
								if (size > 0) {
									list.add(size, userHeadTreeItem);
								} else {
									list.add(userHeadTreeItem);
								}
							}
						}
					}
				}
			}
		}
	}

	public void setDepartmentUserList(List<UserData> list) {
		Platform.runLater(new Runnable() {
			@Override
			public void run() {
				Set<String> keySet = departmentTreeItemMap.keySet();
				for (String key : keySet) {
					TreeItem<Object> departmentItem = departmentTreeItemMap.get(key);
					if (null != departmentItem) {
						List<TreeItem<Object>> nodeList = new ArrayList<TreeItem<Object>>();
						ObservableList<TreeItem<Object>> list = departmentItem.getChildren();
						for (TreeItem<Object> userItem : list) {
							if (userItem.getValue() instanceof SimpleHead) {
								nodeList.add(userItem);
							}
						}
						list.removeAll(nodeList);
					}
				}
			}
		});
	}

	@Override
	public void clearDepartmentList() {
		departmentTreeItemMap.clear();
		Platform.runLater(new Runnable() {
			@Override
			public void run() {
				root.getChildren().clear();
				departmentListPane.clearItem();
			}
		});
	}
	
	@Override
	public void setDepartmentList(List<Department> departmentList) {
		Platform.runLater(new Runnable() {
			@Override
			public void run() {
				
				Set<String> keySet = departmentTreeItemMap.keySet();
				for (String key : keySet) {
					TreeItem<Object> treeItem = departmentTreeItemMap.get(key);
					if (null != treeItem) {
						treeItem.getChildren().clear();
					}
				}
				if (null != departmentList) {
					for (Department department : departmentList) {
						String departmentId = department.getId();
						TreeNodePane node = getDepartmentPane(departmentId);
						setDepartmentInfo(department, node);
					}
					joinSuperior(departmentList);
					for (Department department : departmentList) {
						String departmentId = department.getId();
						addOrUpdate(department);
						setUserHeadList(departmentId);
					}
				}
			}
		});
	}
}
